<?php

namespace Api\Event;

use Api\Event\CacheEvent;
use Api\Event\Cache\UserActionWeightEvent;
use Api\Event\Cache\UserDailyTopEvent;
use Think\Log;

/** 
 * 静态数据统一处理接口
 * @author Legend. <xcx_legender@qq.com>
 * @param 
 * @return 
 */

class StatisEvent extends BaseEvent 
{

	const QUEUE_URI = '';
	const STAT_APP_ID = 'ea9819c4eaa047d49d5f85a6ee25957d';

	public function inRank($video_id, $step = 1)
	{
		$Redis = CacheEvent::instance(7);
		$date = date('Ymd');
		$month = date('Ym');
		$week = date('YW');
		$queueKeys = [
				"IMBA.STATIS.TOP10.DAILY.{$date}",
				"IMBA.STATIS.TOP10.WEEK.{$week}",
				"IMBA.STATIS.TOP10.MONTH.{$month}",
			];
		$expireAt = [
			date('Ymd', strtotime('+1 day')), // 存活到明日
			date('Ymd', strtotime('next Monday')), // 存活到下周
			date('Ym01', strtotime('next month')), // 存活到下个月
		];
		foreach ($queueKeys as $i => $key) {
			$exists = $Redis->exists($key);
			$Redis->zIncrBy($key, $step, $video_id);
			if (!$exists){
				$Redis->expireAt(strtotime($expireAt[$i]));
			}
		}
		
	}

	// 使用队列进行用户数据的统计
	// 加入 对视频 / 用户操作的权重+
	
	//  增减视频的 播放 评论 点赞 收藏 的统计数据  针对视频  用户进行的操作
	public function operStatisVideo($vid,$uid = 0, $field = 'play', $step = 1, $extend = [])
	{
		Log::record("[STATIS OPER]",'DEBUG');
		$field_pass = ['play', 'zan', 'favour', 'comments', 'share', 'submit'];
		if (!in_array($field, $field_pass)) return;
		$video = event('Video')->info($vid);
		// 增加视频的统计
		$this->doQueue('video', $vid, [$field => $step], $extend);

		// 增加视频用户的统计
		if ($video['uid'] > 0){
			$user = event('User')->info($video['uid']);
			$user && $this->operStatisVideoUser($video['uid'], $field, $step);
		}

		// 增加本用户的统计
		$uid > 0 && $this->operStatisUser($uid, $field, $step);
		// 更新缓存
		event('Cache')->videoStatis($vid, 'incr', $field, $step);
		Log::save();
	}

	// 增加视频用户的相同统计信息
	public function operStatisVideoUser($uid, $field, $step = 1)
	{

		$field_pass = ['play', 'zan', 'favour', 'comments', 'share'];
		if (!in_array($field, $field_pass)) return;

		$action = 'video_'.$field;
		$uid > 0 &&  self::updateUserTopWeight($uid, $action);
		$this->doQueue('video_user', $uid, [$field => $step]);
	}

	// 增加用户的操作统计信息
	public function operStatisUser($uid, $field, $step = 1)
	{
		$field_pass = ['zan', 'favour', 'comments', 'share'];
		if (!in_array($field, $field_pass)) return;
		$action = 'user_'.$field;
		$uid > 0 && self::updateUserTopWeight($uid, $action);
		$this->doQueue('user', $uid, [$field => $step]);
	}

	// 上报应用的信息
	public function operStatisTool($action, $step, $extend = '')
	{
		$action_pass = ['install', 'open', 'uninstall', 'record', 'submit', 'cancel'];
		if (!in_array($action, $action_pass)) return;
		$this->doQueue('app', 0, [$action => $step], $extend);
	}


	// 增加用户的每日排行权重
	public function updateUserTopWeight($uid, $action)
	{
		// 获取配置数据
		$configures = UserActionWeightEvent::get();

		if (!$configures || empty($configures[$action])){
			return;
		}
		$config = $configures[$action];
		$max = $config[1];
		// 查找当前用户的操作是否到最大值
		$date = date('Ymd');
		$uid  = (int)$uid;
		$dailyServ = service('UserDailyOperStat');
		$map = [
			'date'   => $date, 
			'uid'    => $uid,
			'action' => $action
		];
		$res = $dailyServ->where($map)->find();
		if ($max > 0 && $max <= $res['times']){
			return;
		}

		// 记录用户操作
		if ($res){
			$res['times'] +=1;
			$dailyServ->where($map)->setInc('times', 1);
		}else{
			$save = $map;
			$save['times'] = 1;
			$dailyServ->add($save);
		}
		
		// 给用户增加排行权重
		$score = $config[0];
 		UserDailyTopEvent::set($date, $uid, $score);
	}

	// 用户行为
	public function operUserAction($data)
	{
		$param = [
			'platform' 		=> (int)$data['platform'],
			'object_type' 	=> 'user_action',
			'object_class'  => 'action',
			'mac'			=> $data['mac'],
			'object_id'     => (int)$data['uid'],
			'step'			=> 1,
			'extend'		=> $data['data'],
			'ts'			=> NOW_TIME*1000,
		];
		$param = json_encode($param);
		$this->awsStatRequest($param);
	}


	/** 
	 * [加入统计队列]
	 * @author Legend. <xcx_legender@qq.com>
	 * @param 
	 * @return 
	 */
	protected function doQueue($type, $id, $stat, $extend = '')
	{
		// $api = C('QUEUE_DOMAIN').'/datamining/add_stat';
		// $param = [
		// 	'object_type' => $type,
		// 	'object_id'   => (int)$id,
		// 	'stat'        => json_encode($stat)
		// ];
		if ($stat){
			foreach ($stat as $key => $step) {
				$param = json_encode([
					'platform'     => (int)defined('PLATFORM') ? PLATFORM : 0, 
					'object_type'  => $type, 
					'object_class' => $key,
					'object_id'    => (int)$id,
					'step'         => (int)$step, 
					'extend'       => $extend ?: '',
					'ts'           => time()*1000,
				]);
				$this->awsStatRequest($param);
				// $header = [
				// 	 'Content-Type:application/json'
				// ];
				// $res = http_request($api, $param, $header, 'POST');
				// Log::record("[DEBUG] - [STATIS QUEUE] - [API: {$api} - PARAM: {$param} - RESULT: {$res} ]", 'DEBUG');
			}
		}
		// print_r($res);
	}

	protected function awsStatRequest($data)
	{
		// $api = C('STATIS_LOG_API');
		// $param = [
		// 	'ts'     => time()*1000,
		// 	'appId'  => self::STAT_APP_ID,
		// 	'data'   => $data,
		// ];
		// $res = http_request($api, $param, '', 'POST');
		event('LocalClient')->doRequest('statis', ['data' => $data]);
		$logParam = json_encode($param);
		Log::record("[DEBUG] - [STATIS QUEUE] - [API: {$api} - PARAM: {$logParam} - RESULT: {$res} ]", 'DEBUG');
		Log::save();
	}

	public function doLocalStatis($action, $platform, $step = 1, $extend = [])
	{
		// $Redis = CacheEvent::instance(7);
		// $hashkey = "IMBA.STATIS.DAILY.".date('Ymd');
		// $key = "$action.$platform";
		// $Redis->hIncrBy($hashkey, $key, $step);

		if ($action != 'register') {
			return;
		}
		$param = json_encode([
			'platform'     => $platform, 
			'object_type'  => 'user', 
			'object_class' => $action,
			'object_id'    => !empty($extend['uid']) ? $extend['uid']: 0,
			'step'         => $step, 
			'extend'       => $extend ?: '',
			'ts'           => NOW_TIME*1000,
		]);
		$this->awsStatRequest($param);


	}

	public function operPcLogin($uid)
	{
		$api = C('QUEUE_DOMAIN').'/datamining/user_awake';
		$param = [
			'openid' => $uid,
		];
		$res = http_request($api, $param, false, 'POST');
	}

	// 记录登录信息..  来源/设备/用户
	public function operLogin($userId, $mac, $platform = 0)
	{
		$mac && $extend['mac'] = $mac;
		$param = json_encode([
			'platform'     => $platform, 
			'object_type'  => 'user', 
			'object_class' => 'login',
			'object_id'    => $userId,
			'step'         => 1, 
			'extend'       => $extend ?: '',
			'ts'           => NOW_TIME*1000,
		]);
		$this->awsStatRequest($param);
		// $header = [
		// 	 'Content-Type:application/json'
		// ];
		// $res = http_request($api, $param, $header, 'POST');
		// Log::record("[DEBUG] - [STATIS QUEUE] - [API: {$api} - PARAM: {$param} - RESULT: {$res} ]", 'DEBUG');

		// $platforms = [
		// 	1 => 'android',
		// 	2 => 'ios',
		// 	5 => 'pc',
		// ];
		// if (array_key_exists($platform, $platforms)){
		// 	$res = event('AppVersion')->getLatest($platform);
		// 	$appVersion = $res['internal_version'];
		// }
		// $appVersion = $appVersion ?: 'default';
		// $platform = in_array($platform, range(1,5)) ? $platform : 4;
		// $ts = NOW_TIME;

		// $param = compact('platform', 'userId', 'appVersion', 'ts');
		// $res = http_request(C('QUEUE_DOMAIN').'/user/login', $param, false, 'POST');
	}

	public function operDownload($platform, $appVersion)
	{
		if (!defined('PLATFORM'))define('PLATFORM', $platform);
		$this->doQueue( 'app', 0, ['download' => 1], ['version' => $appVersion] );
		// $ts = NOW_TIME;
		// $param = compact('platform', 'appVersion', 'ts');
		// $res = http_request(C('QUEUE_DOMAIN').'/user/download', $param, false, 'POST');
	}

	public function operDevice($platform, $mac, $stat)
	{
		// $ts    = NOW_TIME;
		// $stat  = json_encode($stat);
		// $param = compact('platform', 'devId', 'ts', 'stat');
		// // echo C('QUEUE_DOMAIN').'/device/add_info';print_r($param);exit;
		// $res   = http_request(C('QUEUE_DOMAIN').'/device/add_info', $param, false, 'POST');
		// // print_r($res);
		// $res = json_decode($res);
		// if ($res->code != 0){
		// 	\Think\Log::record('STAT QUEUE RES: ' . $res->message, 'DEBUG');
		// }
		
		$mac && $extend['mac'] = $mac;
		$stat && $extend = array_merge($extend, $stat);
		$param = json_encode([
			'platform'     => $platform, 
			'object_type'  => 'app', 
			'object_class' => 'device',
			'object_id'    => 0,
			'step'         => 1, 
			'extend'       => $extend ?: '',
			'ts'           => NOW_TIME*1000,
		]);
		$this->awsStatRequest($param);
	}



	################################################

	public function incrVideoStatis($video_id, $field, $step = 1)
	{
		$video = event('Video')->info($video_id);
		if (!in_array($field, ['play', 'favour', 'zan', 'comments']))
		{
			return;
		}
		$date = date('Y-m-d', NOW_TIME);
		$map = ['date' => $date, 'video_id' => (int) $video_id];

		$vdaily = model('VideoDaily')->where($map)->find();
		if ($vdaily)
		{
			// $save = $vdaily;
			$res = model('VideoDaily')->where($map)->setInc($field);
		}
		else
		{
			$save = $map;
			$save[$field] = 1;
			$save['uid']  = $video['uid'];
			$res = model('VideoDaily')->add($save);
		}
		return $res;
	}
	
	public function decrVideoStatis($video_id, $field, $step = 1)
	{
		if (!in_array($field, ['play', 'favour', 'zan', 'comments']))
		{
			return;
		}
		$date = date('Y-m-d', NOW_TIME);
		$map = ['date' => $date, 'video_id' => (int) $video_id];
		$res = model('VideoDaily')->where($map)->setDec($field);
		return $res;
	}


	public function incrUserStatis($uid, $field, $step = 1)
	{
		if (!in_array($field, ['favour', 'zan', 'comments']))
		{
			return;
		}
		$date = date('Y-m-d', NOW_TIME);
		$map = ['date' => $date, 'uid' => (int) $uid];

		$vdaily = model('UserDaily')->where($map)->find();
		if ($vdaily)
		{
			// $save = $vdaily;
			$res = model('UserDaily')->where($map)->setInc($field);
		}
		else
		{
			$save = $map;
			$save[$field] = 1;
			$res = model('UserDaily')->add($save);
		}
		return $res;
	}

	public function decrUserStatis($uid, $field, $step = 1)
	{
		if (!in_array($field, ['play', 'favour', 'zan', 'comments']))
		{
			return;
		}
		$date = date('Y-m-d', NOW_TIME);
		$map = ['date' => $date, 'uid' => (int) $uid];
		$res = model('UserDaily')->where($map)->setDec($field);
		return $res;
	}

	
	#################################################




}
